#pragma once

namespace zzz{
template<typename T>
class Complex : public Vector<2, T>
{
  using Vector<2, T>::v;
public:
  Complex():Vector<2, T>(0, 0){}
  explicit Complex(const VectorBase<2, T> &v):Vector<2, T>(v){}
  explicit Complex(T r, T i):Vector<2, T>(r, i){}

  using Vector<2, T>::operator[];
  T& Real(){return v[0];}
  const T& Real() const {return v[0];}
  T& Imag(){return v[1];}
  const T& Imag() const {return v[1];}

  using Vector<2, T>::operator+;
  using Vector<2, T>::operator-;

  void operator*=(const VectorBase<2, T>& other)
  {
    T r=Real()*other.Real()-Imag()*other.Imag();
    T i=Real()*other.Imag()+Imag()*other.Real();
    v[0]=r; v[1]=i;
  }
  const Complex<T>& operator*(const VectorBase<2, T>& other)
  {
    return Complex(Real()*other.Real()-Imag()*other.Imag(),Real()*other.Imag()+Imag()*other.Real());
  }
};

typedef Complex<double> Complexd;
typedef Complex<float> Complexf;
}
